package org.bmi.gwt.examples.transaction.client;

import java.util.Date;

import org.bmi.gwt.examples.transaction.shared.MethodsTestProxy;
import org.bmi.gwt.mi.client.channel.Connection;
import org.bmi.gwt.mi.client.events.ConnectionHandler;
import org.bmi.gwt.mi.shared.BroadChannel;
import org.bmi.gwt.mi.shared.Channel;
import org.bmi.gwt.mi.shared.MiTransaction;
import org.bmi.gwt.mi.shared.callbacks.BindCallback;
import org.bmi.gwt.mi.shared.communication.var.ReturnVar;
import org.bmi.gwt.mi.shared.exceptions.InvalidArgumentException;
import org.bmi.gwt.mi.shared.exceptions.MiException;
import org.bmi.gwt.mi.shared.exceptions.NameParseException;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

public class TransactionTest implements EntryPoint
{
	/*
	 * This example attempts to explain how a transaction works, and how in the
	 * proxy version of a target object methods can present another signature,
	 * returning and/or accepting parameters of another type like other proxy or
	 * ReturnVar.
	 */

	@Override
	public void onModuleLoad()
	{
		Connection.createConnection(new ConnectionHandler()
		{
			@Override
			public void onException(Exception e)
			{
				GWT.log("an error occurred: ", e);
			}

			@Override
			public void onConnectionBegin(Connection connection)
			{
				try
				{
					Channel qListen = connection.getChannel("org.bmi.gwt.mi.test.transaction");
					BroadChannel qSend = connection.getChannel("org.bmi.gwt.mi.test.transaction");

					/* A transaction is created... */

					final MiTransaction t = qSend.createTransaction();

					/* ...and a proxy is open. */
					final MethodsTestProxy proxy = t.proxyToNewObject(MethodsTestProxy.class,
							"<value provided by constructor>");

					qListen.bind(new BindCallback()
					{
						@Override
						public void onError(MiException error)
						{
							GWT.log("An error occurred: " + error);
						}

						@Override
						public void onBound(Channel channel)
						{
							final TextBox echoBox = new TextBox();

							Button sendButton = new Button("Send", new ClickHandler()
							{
								public void onClick(ClickEvent event)
								{
									/*
									 * The proxy returns a ReturnVar element, a
									 * special parameter that has meaning only
									 * when provided as argument of a function
									 * accepting on object of that type.
									 */
									ReturnVar<Date> date = proxy.returnDate(echoBox.getValue());
									proxy.provideDate(date);

									MethodsTestProxy copy = proxy.getObjectCopy();
									copy.returnDate("The copy of " + echoBox.getValue());

									MethodsTestProxy wrap = proxy.wrap(copy);
									wrap.returnDate("The wrap of " + echoBox.getValue());

									/* This closes the transaction */
									t.commit();
								}
							});

							RootPanel.get().add(echoBox);
							RootPanel.get().add(sendButton);
						}
					});
				}
				catch (NameParseException e)
				{
					e.printStackTrace();
				}
				catch (InvalidArgumentException e)
				{
					e.printStackTrace();
				}
			}
		});
	}
}
